package net.bblot.lottery.api.http;

/**
 * @Title: HttpConnect.java
 * @Package com.hxd.love.http
 * @Description: TODO(用一句话描述该文件做什么)
 * @author 谢会超
 * @date 2015-8-10 上午9:34:32
 * @version V1.0
 */

import android.content.Context;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.text.TextUtils;

import net.bblot.lottery.PackegeConfig;
import net.bblot.lottery.api.result.HttpResult;
import net.bblot.lottery.api.task.HttpTask;
import net.bblot.lottery.util.Logger;

import org.apache.http.HeaderElement;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.ParseException;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpDelete;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpPut;
import org.apache.http.client.methods.HttpRequestBase;
import org.apache.http.client.params.HttpClientParams;
import org.apache.http.entity.StringEntity;
import org.apache.http.entity.mime.MultipartEntity;
import org.apache.http.entity.mime.content.FileBody;
import org.apache.http.entity.mime.content.StringBody;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.params.BasicHttpParams;
import org.apache.http.params.HttpConnectionParams;
import org.apache.http.params.HttpParams;
import org.apache.http.params.HttpProtocolParams;
import org.apache.http.protocol.HTTP;
import org.apache.http.util.EntityUtils;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLEncoder;
import java.net.UnknownHostException;
import java.nio.charset.Charset;
import java.text.MessageFormat;
import java.util.List;

/**
 * @author 谢会超
 * @ClassName: HttpConnect
 * @Description: TODO(这里用一句话描述这个类的作用)
 * @date 2015-8-10 上午9:34:32
 */

public class HttpConnect {
    private static String TAG = "HttpConnect";
    /**
     * 字符编码为utf-8
     */
    private final static String CHARSET = "utf-8";
    /**
     * 设置请求超时20秒钟
     */
    private static final int REQUEST_TIMEOUT = 20 * 1000;
    /**
     * 设置等待数据超时时间20秒钟
     */
    private static final int SO_TIMEOUT = 20 * 1000;

    public static final int Http_get = 1;
    public static final int Http_put = 2;
    public static final int Http_post = 3;

    private static HttpParams makeHttpParams(Context context) {
        HttpParams httpParams = new BasicHttpParams();
        // 设置连接超时和 Socket 超时，以及 Socket 缓存大小
        HttpConnectionParams.setConnectionTimeout(httpParams, 20 * 1000);
        HttpConnectionParams.setSoTimeout(httpParams, 20 * 1000);
        HttpConnectionParams.setSocketBufferSize(httpParams, 8192);
        // 设置重定向，缺省为 true
        HttpClientParams.setRedirecting(httpParams, true);
        String userAgent_format = "Mozilla/5.0 (Linux; U; Android {0}; zh-cn; Build/JDQ39) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30 Love/{1}";
        String versionName = "";
        try {
            PackageManager pm = context.getPackageManager();
            versionName = pm.getPackageInfo(PackegeConfig.PACKAGE_NAME, 0).versionName;
        } catch (NameNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        String userAgent = MessageFormat.format(userAgent_format,
                android.os.Build.VERSION.RELEASE, versionName);
        HttpProtocolParams.setUserAgent(httpParams, userAgent);
        return httpParams;
    }

    public static String makeQurryUrl(String url, List<NameValuePair> params)
            throws UnsupportedEncodingException {
        if (TextUtils.isEmpty(url) || params == null) {
            return url;
        }

        if (url.contains("?")) {
            for (NameValuePair np : params) {
                url = url + "&" + np.getName() + "="
                        + URLEncoder.encode(np.getValue(), CHARSET);
            }

        } else {
            for (int i = 0; i < params.size(); i++) {
                NameValuePair np = params.get(i);
                if (i == 0) {
                    url = url + "?" + np.getName() + "="
                            + URLEncoder.encode(np.getValue(), CHARSET);
                } else {
                    url = url + "&" + np.getName() + "="
                            + URLEncoder.encode(np.getValue(), CHARSET);
                }
            }
        }
        return url;
    }

    /**
     * get请求
     *
     * @param url
     * @return
     */
    public static HttpResult requestForGet(Context context, String url,
                                           List<NameValuePair> params) {
        HttpResult hr = new HttpResult();
        String result = null;
        try {
            Logger.d(TAG, "107" + url);
            // if (params != null && params.size() > 0) {
            // ub.addParameters(params);
            // }
            url = makeQurryUrl(url, params);
            HttpGet httpRequest = new HttpGet(url);
//			httpRequest.addHeader("Authorization", PackegeConfig.access_token);
            Logger.d(TAG, "113");
            // 创建 HttpParams 以用来设置 HTTP 参数（这一部分不是必需的）
            HttpParams httpParams = makeHttpParams(context);
            // 设置连接超时和 Socket 超时，以及 Socket 缓存大小
            DefaultHttpClient client = new DefaultHttpClient(httpParams);

            HttpResponse response = client.execute(httpRequest);
            Logger.d(TAG, "118" + url);
            hr.setSc(response.getStatusLine().getStatusCode());
            HttpResult.parseDateFrom(response, hr);
            // if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK)
            // {
            HttpEntity entity = response.getEntity();
            result = EntityUtils.toString(entity, getContentCharSet(entity));
            hr.setResult(result);
            Logger.d(TAG, "157" + result);
            // }

        } catch (UnsupportedEncodingException e) {

            e.printStackTrace();
        } catch (ClientProtocolException e) {

            e.printStackTrace();
        } catch (UnknownHostException e) {
            e.printStackTrace();
            return hr;
        } catch (IOException e) {

            e.printStackTrace();
            return hr;
        } catch (Exception e) {

            e.printStackTrace();
            Logger.d(TAG, "144");
            return hr;
        }
        return hr;
    }

    private static String getContentCharSet(final HttpEntity entity)
            throws ParseException {

        if (entity == null) {
            throw new IllegalArgumentException("HTTP entity may not be null");
        }
        String charset = null;
        if (entity.getContentType() != null) {
            HeaderElement values[] = entity.getContentType().getElements();
            if (values.length > 0) {
                NameValuePair param = values[0].getParameterByName("charset");
                if (param != null) {
                    charset = param.getValue();
                }
            }
        }

        if (TextUtils.isEmpty(charset)) {
            charset = "UTF-8";
        }
        return charset;
    }

    /**
     * 按指定URL通过POST方式向服务器请求数据
     *
     * @param url    请求的服务器接口地址
     * @param params 包含存储各个POST参数NameValuePair对象的List
     * @return 请求结果；当出现异常或者请求超时等情况时，返回null
     */
    public static HttpResult requestForPost(Context context, String url,
                                            List<NameValuePair> params) {
        HttpResult hr = new HttpResult();
        String result = null;
        try {
            HttpPost httpRequest = new HttpPost(url);
            HttpEntity entity = new UrlEncodedFormEntity(params, HTTP.UTF_8);
            httpRequest.setEntity(entity);
//			httpRequest.addHeader("Authorization", PackegeConfig.access_token);
            // 取得HttpClient
            HttpParams httpParams = makeHttpParams(context);
            HttpClient client = new DefaultHttpClient(httpParams);
            // 执行请求
            HttpResponse response = client.execute(httpRequest);
            hr.setSc(response.getStatusLine().getStatusCode());
            HttpResult.parseDateFrom(response, hr);
            result = EntityUtils.toString(response.getEntity());
            hr.setResult(result);
        } catch (UnsupportedEncodingException e) {

            e.printStackTrace();
        } catch (ClientProtocolException e) {

            e.printStackTrace();
        } catch (UnknownHostException e) {
            e.printStackTrace();
            // Logger.e(TAG, "UnknownHostException e");
            return hr;
        } catch (IOException e) {

            e.printStackTrace();
            return hr;
        }
        // Logger.e(TAG, "requestForPost ready");
        return hr;
    }

    public static HttpResult request(Context context, String url,
                                     final int http_type, List<NameValuePair> qurryParams,
                                     List<NameValuePair> bodyParams, List<File> file_array,
                                     String file_type) {
        HttpResult hr = new HttpResult();
        String result = null;
        try {
            url = makeQurryUrl(url, qurryParams);
        } catch (UnsupportedEncodingException e1) {
            // TODO Auto-generated catch block
            e1.printStackTrace();
        }
        HttpRequestBase httpRequest = null;
        switch (http_type) {
            case HttpTask.HTTP_REQEST_TYPE_GET:
                httpRequest = new HttpGet(url);
                break;
            case HttpTask.HTTP_REQEST_TYPE_PUT:
                httpRequest = new HttpPut(url);
                break;
            case HttpTask.HTTP_REQEST_TYPE_POST:
                httpRequest = new HttpPost(url);
                break;
            case HttpTask.HTTP_REQEST_TYPE_DELETE:
                Logger.d(TAG, "332HttpDelete");
                httpRequest = new HttpDelete(url);
                break;
            default:
                httpRequest = new HttpPost(url);
                break;
        }
//		httpRequest.addHeader("Authorization", PackegeConfig.access_token);
        // 取得HttpClient
        HttpParams httpParams = makeHttpParams(context);
        MultipartEntity reqEntity = new MultipartEntity();
        if (file_array != null && file_array.size() > 0) {
            for (int i = 0; i < file_array.size(); i++) {
                FileBody fileBody = new FileBody(file_array.get(i), "image");
                reqEntity.addPart(file_type, fileBody);
                Logger.d(TAG,
                        "fileBody" + fileBody.getFilename()
                                + fileBody.getContentLength() / 1024 + "");
            }

        }
        if (bodyParams != null) {
            try {
                for (NameValuePair param : bodyParams) {
                    String value = param.getValue();
                    if (!TextUtils.isEmpty(value)) {
                        reqEntity.addPart(param.getName(), new StringBody(
                                value, Charset.forName(CHARSET)));
                    }
                }
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
            }
        }
        switch (http_type) {
            case HttpTask.HTTP_REQEST_TYPE_GET:
                break;
            case HttpTask.HTTP_REQEST_TYPE_PUT:
                HttpPut hp = (HttpPut) httpRequest;
                hp.setEntity(reqEntity);
                break;
            case HttpTask.HTTP_REQEST_TYPE_POST:
                HttpPost hpost = (HttpPost) httpRequest;
                hpost.setEntity(reqEntity);
                break;
            case HttpTask.HTTP_REQEST_TYPE_DELETE:
                break;
            default:
                break;
        }
        Logger.d(TAG, "332");
        // 取得HttpClient
        HttpConnectionParams.setConnectionTimeout(httpParams, REQUEST_TIMEOUT);
        HttpConnectionParams.setSoTimeout(httpParams, SO_TIMEOUT);
        HttpClient client = new DefaultHttpClient(httpParams);
        // 执行请求
        HttpResponse response;
        try {
            Logger.d(TAG, "338" + httpRequest.getURI());
            response = client.execute(httpRequest);
            Logger.d(TAG, "342" + response);
            hr.setSc(response.getStatusLine().getStatusCode());
            HttpResult.parseDateFrom(response, hr);
            result = EntityUtils.toString(response.getEntity());
            Logger.d(TAG, hr.getSc() + "hr.getSc()" + "result=" + result);
            hr.setResult(result);
        } catch (ClientProtocolException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return hr;
    }

    public static HttpResult request(Context context, String url, String content) {
        HttpResult hr = new HttpResult();
        String result = null;
        try {
            HttpPost httpRequest = new HttpPost(url);
            HttpEntity entity = new StringEntity(content, "utf-8");
            httpRequest.setEntity(entity);
//			httpRequest.addHeader("Authorization", PackegeConfig.access_token);
            // 取得HttpClient
            HttpParams httpParams = makeHttpParams(context);
            HttpClient client = new DefaultHttpClient(httpParams);
            // 执行请求
            HttpResponse response = client.execute(httpRequest);
            hr.setSc(response.getStatusLine().getStatusCode());
            HttpResult.parseDateFrom(response, hr);
            result = EntityUtils.toString(response.getEntity());
            hr.setResult(result);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return hr;
    }


    /**
     * @param context
     * @param fileName
     * @param url
     * @param parentPath
     * @return boolean 返回类型
     * @Title: donwLoadFile2
     * @author 谢会超
     * @Description: TODO(下载文件)
     * @date 创建(修改时间) 2015-5-14 下午6:06:49
     */
    public static boolean donwLoadFile(Context context, String fileName,
                                       String url, String parentPath, PercentListener percentListener) {
        if (url == null || TextUtils.isEmpty(parentPath)) {
            return false;
        }
        Logger.d(TAG, "" + url);
        HttpURLConnection urlConnection = null;
        BufferedOutputStream out = null;
        File fileDir = new File(parentPath);
        if (!fileDir.exists()) {
            fileDir.mkdirs();
        }
        File file = new File(parentPath, fileName);
        Logger.d(TAG, file.getAbsolutePath() + "");
        URL url2;
        try {
            url2 = new URL(url);
            urlConnection = (HttpURLConnection) url2.openConnection();
            urlConnection.setReadTimeout(REQUEST_TIMEOUT);
            int responseCode = urlConnection.getResponseCode();
            Logger.d(TAG, "" + responseCode);

            int maxLength = urlConnection.getContentLength();
            int progress = 0;
            int percent = 0;
            final InputStream in = new BufferedInputStream(
                    urlConnection.getInputStream(), 1024);
            out = new BufferedOutputStream(new FileOutputStream(file), 1024);

            int len;
            byte buff[] = new byte[1024];
            while ((len = in.read(buff)) != -1) {
                out.write(buff, 0, len);
                progress += len;
                int temp = (int) (((float) progress / maxLength) * 100);
                if (temp >= 1 && temp > percent) {
                    percent = temp;
                    if (percentListener != null) {
                        percentListener.onPercentUpdate(percent);
                    }
                }
            }
            if (percentListener != null) {
                percentListener.onPercentUpdate(100);
            }
            return true;
        } catch (MalformedURLException e) {
            // TODO Auto-generated catch block

            e.printStackTrace();
            return false;
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
            try {
                out.close();
                return false;
            } catch (Exception ee) {

                boolean flag = file.delete();
                Logger.e(TAG, "下载文件过程出错，试图删除文件，返回值为" + flag);
                return false;
            }

        } finally {
            if (urlConnection != null) {
                urlConnection.disconnect();
            }
            if (out != null) {
                try {
                    out.close();
                } catch (final IOException e) {
                    Logger.e(TAG, "下载文件过程出错， " + e);
                }
            }
        }
    }

    public interface PercentListener {
        void onPercentUpdate(int per);
    }
}